package ace.cmp.controller.spring.data.jdbc.querydsl.rsql.core;

import ace.cmp.data.spring.data.jdbc.querydsl.rsql.core.manager.DtoManager;
import ace.cmp.data.spring.data.jdbc.querydsl.rsql.core.manager.DtoManagerConstructArgs;
import ace.cmp.data.spring.data.jdbc.querydsl.rsql.core.manager.impl.DefaultDtoManagerConstructArgs;
import ace.cmp.data.spring.data.jdbc.querydsl.rsql.core.manager.spring.DtoManagerSpringFactory;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.ResolvableType;

/**
 * @author caspar
 * @date 2023/4/12 17:30
 */
@Slf4j
public abstract class AbstractDtoController<EntityT, EntityDtoT>
    extends AbstractController<EntityT>
    implements InitializingBean {

  @Getter(value = AccessLevel.PROTECTED)
  @Setter(value = AccessLevel.PROTECTED)
  private Class<EntityDtoT> entityDtoClass;

  @Autowired
  private DtoManagerSpringFactory managerSpringFactory;

  protected AbstractDtoController() {
    super();
    ResolvableType resolvableType = ResolvableType.forType(this.getClass());
    this.entityDtoClass = (Class<EntityDtoT>) resolvableType.getSuperType().getGeneric(1).getRawClass();
  }

  @Override
  protected void initManager() {
    DtoManagerConstructArgs<EntityT, Object, EntityDtoT> args = DefaultDtoManagerConstructArgs.<EntityT, Object, EntityDtoT>builder()
        .entityClass(this.getEntityClass())
        .idClass(this.getIdClass())
        .entityDtoClass(this.getEntityDtoClass())
        .build();

    DtoManager<EntityT, ?, EntityDtoT> manager = managerSpringFactory.getOrCreate(args);

    this.setManager(manager);
  }

  protected DtoManager<EntityT, ?, EntityDtoT> getDtoManage() {
    return (DtoManager<EntityT, ?, EntityDtoT>) this.getManager();
  }
}
